package org.xx.armory.httpclient;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public final class SSLContextUtils {
    private static final SSLContext IGNORE_CERTIFICATE_CONTEXT = createIgnoreCertContext();
    private static final HostnameVerifier ALLOW_ALL_HOSTNAME_VERIFIER = createAllowAllHostnameVerifier();

    @SuppressWarnings("unused")
    private SSLContextUtils() {
        throw new AssertionError();
    }

    public static SSLContext ignoreCert() {
        return IGNORE_CERTIFICATE_CONTEXT;
    }

    public static HostnameVerifier allowAllHostname() {
        return ALLOW_ALL_HOSTNAME_VERIFIER;
    }

    private static SSLContext createIgnoreCertContext() {
        try {
            final var sslContext = SSLContext.getInstance("TLS");
            sslContext.init(new KeyManager[0], new TrustManager[]{new IgnoreCertTrustManager()}, new SecureRandom());
            return sslContext;
        } catch (Exception ex) {
            throw new IllegalStateException("Cannot create SSL context", ex);
        }
    }

    private static HostnameVerifier createAllowAllHostnameVerifier() {
        return new AllowAllHostnameVerifier();
    }

    /**
     * HTTPS通信中，不要求验证证书的验证器。
     */
    private static final class IgnoreCertTrustManager
            implements X509TrustManager {
        IgnoreCertTrustManager() {
        }

        public void checkClientTrusted(
                X509Certificate[] chain,
                String authType
        )
                throws CertificateException {
        }

        public void checkServerTrusted(
                X509Certificate[] chain,
                String authType
        )
                throws CertificateException {
        }

        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }

    /**
     * HTTPS通信中，允许证书匹配任何域名的验证器。
     */
    private static class AllowAllHostnameVerifier
            implements HostnameVerifier {
        @Override
        public boolean verify(
                String s,
                SSLSession sslSession
        ) {
            return true;
        }
    }
}
